package api

import (
	"fmt"
	"longmen/server/pkg/common/api_models"
	_const "longmen/server/pkg/common/helper/const"
	"longmen/server/pkg/common/helper/util"
	"longmen/server/pkg/common/services"
	"longmen/server/pkg/grpc_client"
	pb "longmen/server/pkg/protobuf"

	"github.com/labstack/echo/v4"
	"github.com/spf13/cast"
	"google.golang.org/grpc/status"
)

// @Summary 创建问题
// @Description 创建问题
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body api_models.CreateQuestionReq true "body"
// @Success 0 {object} protobuf.CreateQuestionResp "result"
// @Router /api/guess/createQuestion [POST]
func (base *Controller) CreateQuestion(c echo.Context) error {
	r := &pb.CreateQuestionReq{}
	r.AnchorId = cast.ToInt32(c.Get("uid"))

	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.CreateQuestion(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 得我的问题列表
// @Description 得我的问题列表
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body api_models.GetQuestionListReq true "body"
// @Success 0 {object} protobuf.GetQuestionListResp "result"
// @Router /api/guess/getQuestionList [POST]
func (base *Controller) GetQuestionList(c echo.Context) error {
	r := &pb.GetQuestionListReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	r.AnchorId = cast.ToInt32(c.Get("uid"))
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.GetQuestionList(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary  删除一个问题
// @Description  删除一个问题
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body api_models.DelQuestionReq true "body"
// @Success 0 {object} protobuf.DelQuestionResp "result"
// @Router /api/guess/delQuestion [POST]
func (base *Controller) DelQuestion(c echo.Context) error {
	r := &pb.DelQuestionReq{}

	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	r.Uid = cast.ToInt32(c.Get("uid"))
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.DelQuestion(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 创建一场竞猜
// @Description  创建一场竞猜
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body api_models.CreateGuessReq true "body"
// @Success 0 {object} protobuf.CreateGuessResp "result"
// @Router /api/guess/createGuess [POST]
func (base *Controller) CreateGuess(c echo.Context) error {
	r := &pb.CreateGuessReq{}

	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	r.AnchorId = cast.ToInt32(c.Get("uid"))
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.CreateGuess(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary  得一场竞猜信息
// @Description  得一场竞猜信息
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body api_models.GetGuessReq true "body"
// @Success 0 {object} protobuf.GetGuessResp "result"
// @Router /api/guess/getGuess [POST]
func (base *Controller) GetGuess(c echo.Context) error {
	r := &pb.GetGuessReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.GetGuess(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary  封盘
// @Description  封盘
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body protobuf.CloseGuessReq true "body"
// @Success 0 {object} protobuf.CloseGuessResp "result"
// @Router /api/guess/closeGuess [POST]
func (base *Controller) CloseGuess(c echo.Context) error {
	r := &pb.CloseGuessReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	if r.AnchorId == 0 {
		return fmt.Errorf("无效的主播id")
	}
	if r.AnchorId != cast.ToInt32(c.Get("uid")) {
		return fmt.Errorf("只能操作自己发起的竞猜")
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.CloseGuess(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary  取消竞猜
// @Description  取消竞猜
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body protobuf.CancelGuessReq true "body"
// @Success 0 {object} protobuf.CancelGuessResp "result"
// @Router /api/guess/cancelGuess [POST]
func (base *Controller) CancelGuess(c echo.Context) error {
	r := &pb.CancelGuessReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	if r.AnchorId == 0 {
		return fmt.Errorf("无效的主播id")
	}
	if r.AnchorId != cast.ToInt32(c.Get("uid")) {
		return fmt.Errorf("只能操作自己发起的竞猜")
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.CancelGuess(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary  开奖
// @Description  开奖
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body protobuf.SettleGuessReq true "body"
// @Success 0 {object} protobuf.SettleGuessResp "result"
// @Router /api/guess/settleGuess [POST]
func (base *Controller) SettleGuess(c echo.Context) error {
	r := &pb.SettleGuessReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	if r.AnchorId == 0 {
		return fmt.Errorf("无效的主播id")
	}
	if r.AnchorId != cast.ToInt32(c.Get("uid")) {
		return fmt.Errorf("只能操作自己发起的竞猜")
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.SettleGuess(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary  得竞猜订单列表
// @Description  得竞猜订单列表
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body api_models.GetGuessOrderListReq true "body"
// @Success 0 {object} protobuf.GetGuessOrderListResp "result"
// @Router /api/guess/getGuessOrderList [POST]
func (base *Controller) GetGuessOrderList(c echo.Context) error {
	r := &pb.GetGuessOrderListReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	uid := cast.ToInt32(c.Get("uid"))

	if (r.AnchorId != 0 && uid != r.AnchorId) || (r.Uid != 0 && uid != r.Uid) {
		return fmt.Errorf("只能查询与自己相关的记录")
	}
	if r.AnchorId == 0 && r.Uid == 0 {
		r.Uid = uid
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.GetGuessOrderList(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary  得竞猜订单列表
// @Description  得竞猜订单列表
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body api_models.GetGuessOrderReq true "body"
// @Success 0 {object} protobuf.GetGuessOrderResp "result"
// @Router /api/guess/getGuessOrder [POST]
func (base *Controller) GetGuessOrder(c echo.Context) error {
	r := &pb.GetGuessOrderReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	uid := cast.ToInt32(c.Get("uid"))
	if uid != r.AnchorId && uid != r.Uid {
		return fmt.Errorf("只能查询与自己相关的记录")
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.GetGuessOrder(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary  得竞猜列表
// @Description  得竞猜列表
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body api_models.GetGuessListReq true "body"
// @Success 0 {object} protobuf.GetGuessResp "result"
// @Router /api/guess/getGuessList [POST]
func (base *Controller) GetGuessList(c echo.Context) error {
	r := &pb.GetGuessListReq{}

	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	if r.LiveId == 0 { //如果没有live_id，只能查用户自己发起的
		r.AnchorId = cast.ToInt32(c.Get("uid"))
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.GetGuessList(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 参与竞猜
// @Description  参与竞猜
// @Accept  json
// @Produce  json
// @Tags Guess
// @Param   sendBody body api_models.CreateGuessOrderReq true "body"
// @Success 0 {object} protobuf.CreateGuessOrderResp "result"
// @Router /api/guess/createGuessOrder [POST]
func (base *Controller) CreateGuessOrder(c echo.Context) error {
	r := &pb.CreateGuessOrderReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if err := _const.Validate.Struct(r); err != nil {
		return util.BadParam(c, err)
	}
	r.Uid = cast.ToInt32(c.Get("uid"))
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcGuessServer.CreateGuessOrder(ctx, r)
	if err != nil {
		statsErr := status.Convert(err)
		return util.BuildFail(c, 1, statsErr.Message(), err)
	}
	return util.BuildSuccess(c, resp, "")
}

// @Summary 所有竞猜列表
// @Description  所有竞猜列表
// @Accept  json
// @Produce  json
// @Tags Guess
// @Success 0 {object} []api_models.GuessInfo "result"
// @Router /api/guess/list [POST]
func (base *Controller) GuessList(c echo.Context) error {
	var err error
	r := &api_models.GuessListReq{}
	if err := util.Json2Struct(c.Get("body").(string), r); err != nil {
		return util.BadParam(c, err)
	}
	if r.AnchorID == 0 {
		resp, err := services.GetQuessList()
		if err == nil {
			return util.BuildSuccess(c, resp, "")
		}
	} else {
		resp, err := services.GetQuestListByAnchor(r.AnchorID)
		if err == nil {
			return util.BuildSuccess(c, resp, "")
		}
	}

	return util.BuildFail(c, 1, "", err)

}
